package com.kehutong.wwin.service.service;

import com.kehutong.common.errcode.Result;
import com.kehutong.common.util.Token;
import com.kehutong.wwin.service.entity.TagMap;
import com.kehutong.wwin.service.util.WwInHttpClient;
import com.kehutong.wxapi.request.CorpTagAddRequest;
import com.kehutong.wxapi.request.CorpTagDeleteRequest;
import com.kehutong.wxapi.request.CorpTagEditRequest;
import com.kehutong.wxapi.response.CorpTagAddResponse;
import com.kehutong.wxapi.response.CorpTagDeleteResponse;
import com.kehutong.wxapi.response.CorpTagEditResponse;
import com.kehutong.wxapi.service.ExternalContactService;
import org.coraframework.authz.Subject;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.util.Objects;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 同步客户通标签数据到企业微信
 * 1.业务暂时不需要
 * @author: liukunlong
 * @date: 2021-03-18 11:52
 */
@WebService("/wwin-service/tag/wwin")
public class ToWwinTagService {
    @Inject
    private WwInHttpClient httpClient;

    @Inject
    private JdbcSession jdbcSession;


    @Inject
    private ExternalContactService externalContactService;


    /**
     * 新增标签
     * @param token 用户信息
     * @param khtJson 客户通传入Json数据
     * @return 结果对象
     * @throws Exception 异常
     */
    @ReqMapping("/create")
    public Object addCorpTag(Token token, JSONObject khtJson) throws Exception {
        return saveUpdate(token,khtJson);
    }




    /**
     * 新增或更新标签组及标签
     * 1.标签组没有映射(则所有数据新增,绑定映射)
     * 2.标签组有映射,标签部分有映射,部分没有映射(先更新标签组,标签有映射更新,没有映射新增,然后绑定映射)
     * @param token 用户信息
     * @param khtJson 客户通传入Json数据
     * @return 结果对象
     * @throws Exception 异常
     */
    private Object saveUpdate(Token token, JSONObject khtJson) throws Exception {
        TagMap tagGroupMap = getTagByKhtId(khtJson.getString("id"));
        if (Objects.isNull(tagGroupMap)) {
            return save(token,khtJson);
        }else{
            //更新
            CorpTagEditRequest corpTagGroupEditRequest = new CorpTagEditRequest();
            corpTagGroupEditRequest.setAccessToken(httpClient.getContactAccessToken(token));
            corpTagGroupEditRequest.setId(tagGroupMap.getId());
            corpTagGroupEditRequest.setName(khtJson.getString("name"));
            corpTagGroupEditRequest.setOrder(1);
            CorpTagEditResponse corpTagGroupEditResponse = externalContactService.editCorpTag(corpTagGroupEditRequest);
            if (corpTagGroupEditResponse.getErrcode() != 0) {
                return Result.error(corpTagGroupEditResponse.getErrcode(), corpTagGroupEditResponse.getErrmsg());
            }

            //TODO 标签部分有映射,部分没有映射(有映射更新,没有映射新增,然后绑定映射)
            JSONArray tagJsonArray = khtJson.getJSONArray("childList");
            if (Objects.nonEmpty(tagJsonArray)) {
                //增量新增的标检数组
                JSONArray addTagJsonArray=new JSONArray();
                for(Object obj:tagJsonArray){
                    JSONObject tagJSONObject = (JSONObject) obj;
                    TagMap tagMap = getTagByKhtId(tagJSONObject.getString("id"));

                    if(Objects.isNull(tagMap)){
                        //挑选出没有映射的数据然后保存在新的数组中
                        addTagJsonArray.add(tagJSONObject);
                    }else{
                        //有映射的标签进行更新
                        CorpTagEditRequest corpTagEditRequest = new CorpTagEditRequest();
                        corpTagEditRequest.setAccessToken(httpClient.getContactAccessToken(token));
                        corpTagEditRequest.setId(tagMap.getId());
                        corpTagEditRequest.setName(tagJSONObject.getString("name"));
                        corpTagEditRequest.setOrder(1);
                        CorpTagEditResponse corpTagEditResponse = externalContactService.editCorpTag(corpTagEditRequest);
                        if (corpTagEditResponse.getErrcode() != 0) {
                            return Result.error(corpTagEditResponse.getErrcode(), corpTagEditResponse.getErrmsg());
                        }
                    }
                }
                //没有映射的标签进行新增,然后绑定映射
                if (Objects.nonEmpty(addTagJsonArray)) {
                    khtJson.put("childList",addTagJsonArray);
                    return save(token,khtJson);
                }
            }
        }
        return Result.success();
    }



    /**
     * 新增签组及标签
     * @param token 用户信息
     * @param khtJson 客户通传入Json数据
     * @return 结果对象
     * @throws Exception 异常
     */
    private Object save(Token token, JSONObject khtJson) throws Exception {
        TagMap tagGroupMap = getTagByKhtId(khtJson.getString("id"));
        if (Objects.isNull(tagGroupMap)) {
            CorpTagAddRequest corpTagAddRequest = new CorpTagAddRequest();
            corpTagAddRequest.setAccessToken(httpClient.getContactAccessToken(token));
            JSONArray tagJsonArray = khtJson.getJSONArray("childList");
            //腾讯规定新增必须存在标签组及标签
            if (Objects.nonEmpty(tagJsonArray)) {
                //标签名称与客户通标签标志映射
                Map<String,String> nameToIdMapping=new HashMap<>();
                List<CorpTagAddRequest.TagDTO> addTagList = new ArrayList<>();
                tagJsonArray.forEach((obj) -> {
                    JSONObject tagJSONObject = (JSONObject) obj;
                    CorpTagAddRequest.TagDTO addTag = new CorpTagAddRequest.TagDTO();
                    addTag.setName(tagJSONObject.getString("name"));
                    addTag.setOrder(1);
                    addTagList.add(addTag);
                    nameToIdMapping.put(tagJSONObject.getString("name"),tagJSONObject.getString("id"));
                });
                corpTagAddRequest.setTag(addTagList);
                corpTagAddRequest.setGroupName(khtJson.getString("name"));
                corpTagAddRequest.setOrder(1);
                CorpTagAddResponse corpTagAddResponse = externalContactService.addCorpTag(corpTagAddRequest);
                if (corpTagAddResponse.getErrcode() != 0) {
                    return Result.error(corpTagAddResponse.getErrcode(), corpTagAddResponse.getErrmsg());
                }
                CorpTagAddResponse.TagGroupDTO tagGroup = corpTagAddResponse.getTagGroup();

                //客户通标签标志
                String groupId = khtJson.getString("id");
                tagGroupMap = Pool.newInstance(TagMap.class, tagGroup.getGroupId());
                tagGroupMap.setKhtid(groupId);
                jdbcSession.insert(tagGroupMap);
                List<CorpTagAddResponse.TagGroupDTO.TagDTO> tagList = tagGroup.getTag();
                if (Objects.nonEmpty(tagList)) {
                    for(CorpTagAddResponse.TagGroupDTO.TagDTO tag:tagList){
                        TagMap tagMap = Pool.newInstance(TagMap.class, tag.getId());
                        tagMap.setKhtid(nameToIdMapping.get(tag.getName()));
                        jdbcSession.insert(tagMap);
                    }
                }
            }
        }
        return Result.success();
    }

    /**
     * 更新企业微信标签库的标签数据
     * @param token 用户信息
     * @param khtJson 客户通传入Json数据
     * @return 结果对象
     * @throws Exception 异常
     */
    @ReqMapping("/update")
    public Object editCorpTag(Token token, JSONObject khtJson) throws Exception {
        return saveUpdate(token,khtJson);
    }

    /**
     * 删除企业微信标签数据
     * @param token 用户信息
     * @param khtJson 客户通传入Json数据
     * @return 结果对象
     * @throws Exception 异常
     */
    @ReqMapping("/delete")
    public Object delCorpTag(Token token, JSONObject khtJson) throws Exception {

        TagMap tagMap = getTagById(khtJson.getString("id"));
        if (Objects.nonNull(tagMap)) {
            boolean isGroup = khtJson.getBooleanValue("group");
            List<String> idList = new ArrayList<>();
            idList.add(tagMap.getId());
            CorpTagDeleteRequest corpTagDeleteRequest = new CorpTagDeleteRequest();
            corpTagDeleteRequest.setAccessToken(httpClient.getContactAccessToken(token));
            if (isGroup) {
                corpTagDeleteRequest.setGroupId(idList);
            } else {
                corpTagDeleteRequest.setTagId(idList);
            }
            CorpTagDeleteResponse corpTagDeleteResponse = externalContactService.deleteCorpTag(corpTagDeleteRequest);
            if (corpTagDeleteResponse.getErrcode() != 0) {
                return Result.error(corpTagDeleteResponse.getErrcode(), corpTagDeleteResponse.getErrmsg());
            }
            jdbcSession.deleteById(tagMap);
            //如果删除的是标签组则级联删除标签组下面标签的映射关系
            if (isGroup) {
                JSONArray tagJsonArray = khtJson.getJSONArray("childList");
                if (Objects.nonEmpty(tagJsonArray)) {
                    tagJsonArray.forEach((obj) -> {
                        JSONObject tagJSONObject = (JSONObject) obj;
                        TagMap tag = getTagById(tagJSONObject.getString("id"));
                        if (Objects.nonNull(tag)) {
                            jdbcSession.deleteById(tag);

                        }
                    });
                }

            }
        }
        return Result.success();
    }

    /**
     * 根据微信标志获取映射信息
     *
     * @param id 微信标志
     * @return 映射信息
     */
    public TagMap getTagById(String id) {
        return Pool.get(TagMap.class, id);
    }

    /**
     * 根据客户通标志获取映射信息
     * @param khtid 客户通标志
     * @return 映射信息
     */
    public TagMap getTagByKhtId(String khtid) {
        List<TagMap> exe = jdbcSession.findArray(TagMap.class)
                .eq("khtid",khtid).exe();
        if(Objects.isEmpty(exe)){
            return null;
        }
        return exe.get(0);
    }

    /**
     * 根据规则产生第三方标签标志
     * @param corpNo
     * @param type
     * @param name
     * @return
     */
    public static String toKhtId(String corpNo,String type,String name) {
        String thirdPartySource="1";
        StringBuilder buf = new StringBuilder(corpNo).append("_")
                .append(thirdPartySource).append("_")
                .append(type).append("_")
                .append(name.toUpperCase());
        return Subject.encrypt(buf.toString());
    }
}
